Sensor Fusion for Kinetis MCUs (ISSDK/KSDK version)
debug.c File Reference
+ Include dependency graph for debug.c:

Go to the source code of this file.

Functions

void ApplyPerturbation (SensorFusionGlobals *sfg)
 

Detailed Description

The ApplyPerturbation function applies a user-specified step function to prior fusion results which is then "released" in the next fusion cycle. When used in conjustion with the NXP Sensor Fusion Toolbox, this provides a visual indication of the dynamic behavior of the library.

Also included is some code for white-box testing within the IAR debug environment. It can be used to evaluate propagation delays for tilt and eCompass algorithms. It makes no sense with regard to "Rotation", because that algorithm is simple gyro integration, and will never return to the starting point. It will also overestimate delays for the kalman filters, as there is no actual gyro data corresponding to the simulated step function. So those filters are not operating as they would in the normal world.

Definition in file debug.c.

Function Documentation

void ApplyPerturbation ( SensorFusionGlobals sfg)

The ApplyPerturbation function applies a user-specified step function to prior fusion results which is then "released" in the next fusion cycle. When used in conjustion with the NXP Sensor Fusion Toolbox, this provides a visual indication of the dynamic behavior of the library. This function is normally involved via the "sfg." global pointer.

Definition at line 53 of file debug.c.

54 {
55 #ifdef INCLUDE_DEBUG_FUNCTIONS
56  // volatile keyword used to force compiler not to optimize out these
57  // variables. this does unfortunately result in a couple of warnings (which
58  // can be ignored) farther down in this code.
59  volatile static uint16_t iTestProgress; ///< Perturbation test status
60  volatile static uint16_t iTestDelay = 0; ///< Measured delay
61  volatile static uint16_t iTestAngle = 0; ///< Integer Residual angle associated with measured delay
62  volatile float angle=0.0f; ///< Float Residual angle associated with measured delay
63  volatile static float threshold=0;
64  static Quaternion StartingQ = {
65  .q0 = 1.0,
66  .q1 = 0.0,
67  .q2 = 0.0,
68  .q3 = 0.0
69  };
70  Quaternion CurrentQ = {
71  .q0 = 1.0,
72  .q1 = 0.0,
73  .q2 = 0.0,
74  .q3 = 0.0
75  };
76  // cache local copies of control flags so we don't have to keep dereferencing pointers below
77  quaternion_type quaternionPacketType;
78  quaternionPacketType = sfg->pControlSubsystem->QuaternionPacketType;
79 
80  Quaternion ftmpq; // scratch quaternion
81 
82  // calculate the test perturbation
83  switch (sfg->iPerturbation)
84  {
85  case 1: // 180 degrees about X
86  ftmpq.q0 = 0.0F;
87  ftmpq.q1 = 1.0F;
88  ftmpq.q2 = 0.0F;
89  ftmpq.q3 = 0.0F;
90  threshold = 90.0;
91  break;
92 
93  case 2: // 180 degrees about Y
94  ftmpq.q0 = 0.0F;
95  ftmpq.q1 = 0.0F;
96  ftmpq.q2 = 1.0F;
97  ftmpq.q3 = 0.0F;
98  threshold = 90.0;
99  break;
100 
101  case 3: // 180 degrees about Z
102  ftmpq.q0 = 0.0F;
103  ftmpq.q1 = 0.0F;
104  ftmpq.q2 = 0.0F;
105  ftmpq.q3 = 1.0F;
106  threshold = 90.0;
107  break;
108 
109  case 4: // -90 degrees about X
110  ftmpq.q0 = ONEOVERSQRT2;
111  ftmpq.q1 = -ONEOVERSQRT2;
112  ftmpq.q2 = 0.0F;
113  ftmpq.q3 = 0.0F;
114  threshold = 45.0;
115  break;
116 
117  case 5: // +90 degrees about X
118  ftmpq.q0 = ONEOVERSQRT2;
119  ftmpq.q1 = ONEOVERSQRT2;
120  ftmpq.q2 = 0.0F;
121  ftmpq.q3 = 0.0F;
122  threshold = 45.0;
123  break;
124 
125  case 6: // -90 degrees about Y
126  ftmpq.q0 = ONEOVERSQRT2;
127  ftmpq.q1 = 0.0F;
128  ftmpq.q2 = -ONEOVERSQRT2;
129  ftmpq.q3 = 0.0F;
130  threshold = 45.0;
131  break;
132 
133  case 7: // +90 degrees about Y
134  ftmpq.q0 = ONEOVERSQRT2;
135  ftmpq.q1 = 0.0F;
136  ftmpq.q2 = ONEOVERSQRT2;
137  ftmpq.q3 = 0.0F;
138  threshold = 45.0;
139  break;
140 
141  case 8: // -90 degrees about Z
142  ftmpq.q0 = ONEOVERSQRT2;
143  ftmpq.q1 = 0.0F;
144  ftmpq.q2 = 0.0F;
145  ftmpq.q3 = -ONEOVERSQRT2;
146  threshold = 45.0;
147  break;
148 
149  case 9: // +90 degrees about Z
150  ftmpq.q0 = ONEOVERSQRT2;
151  ftmpq.q1 = 0.0F;
152  ftmpq.q2 = 0.0F;
153  ftmpq.q3 = ONEOVERSQRT2;
154  threshold = 45.0;
155  break;
156 
157  default: // No rotation
158  ftmpq.q0 = 1.0F;
159  ftmpq.q1 = 0.0F;
160  ftmpq.q2 = 0.0F;
161  ftmpq.q3 = 0.0F;
162  break;
163  }
164 
165  switch (quaternionPacketType) {
166 #if F_3DOF_G_BASIC
167  case (Q3):
168  CurrentQ = sfg->SV_3DOF_G_BASIC.fLPq;
169  qAeqAxB(&(sfg->SV_3DOF_G_BASIC.fLPq), &ftmpq);
170  break;
171 #endif
172 #if F_3DOF_B_BASIC
173  case (Q3M):
174  CurrentQ = sfg->SV_3DOF_B_BASIC.fLPq;
175  qAeqAxB(&(sfg->SV_3DOF_B_BASIC.fLPq), &ftmpq);
176  break;
177 #endif
178 #if F_3DOF_Y_BASIC
179  case (Q3G):
180  CurrentQ = sfg->SV_3DOF_Y_BASIC.fq;
181  qAeqAxB(&(sfg->SV_3DOF_Y_BASIC.fq), &ftmpq);
182  break;
183 #endif
184 #if F_6DOF_GB_BASIC
185  case (Q6MA):
186  CurrentQ = sfg->SV_6DOF_GB_BASIC.fLPq;
187  qAeqAxB(&(sfg->SV_6DOF_GB_BASIC.fLPq), &ftmpq);
188  break;
189 #endif
190 #if F_6DOF_GY_KALMAN
191  case (Q6AG):
192  CurrentQ = sfg->SV_6DOF_GY_KALMAN.fqPl;
193  qAeqAxB(&(sfg->SV_6DOF_GY_KALMAN.fqPl), &ftmpq);
194  break;
195 #endif
196 #if F_9DOF_GBY_KALMAN
197  case (Q9):
198  CurrentQ = sfg->SV_9DOF_GBY_KALMAN.fqPl;
199  qAeqAxB(&(sfg->SV_9DOF_GBY_KALMAN.fqPl), &ftmpq);
200  break;
201 #endif
202  default:
203  CurrentQ.q0 = 1.0;
204  CurrentQ.q1 = 0.0;
205  CurrentQ.q2 = 0.0;
206  CurrentQ.q3 = 0.0;
207  break;
208  }
209 
210  // Begin of code for white-box testing - requires IAR debugger
211  switch (iTestProgress) {
212  case 0: // no test in progress, check to see if we should start one
213  if (sfg->iPerturbation>0) {
214  // Start Test
215  iTestProgress = 1;
216  sfg->iPerturbation = 0;
217  iTestDelay = 0;
218  iTestAngle = 0;
219  // We'll need the complex conjugate of the starting quaternion
220  StartingQ.q0 = CurrentQ.q0;
221  StartingQ.q1 = -1 * CurrentQ.q1;
222  StartingQ.q2 = -1 * CurrentQ.q2;
223  StartingQ.q3 = -1 * CurrentQ.q3;
224  }
225  break;
226  default: // Test in progress, check to see if trigger reached
227  iTestDelay += 1;
228  qAeqAxB(&CurrentQ, &StartingQ);
229  angle = 2 * F180OVERPI * acos(CurrentQ.q0);
230  angle = fmod(fabs(angle), 180.0);
231  iTestAngle = (uint16_t) (10 * angle);
232  // In IAR, you can use a Log breakpoint to monitor "return to stationary pose".
233  // Use the following expression in the Message field and check the
234  // checkbox for C-Spy macro. Then Click any of the "Test" buttons
235  // in the Sensor Fusion Toolbox and monitor the results in the Messages window.
236  //"Delay=", iTestDelay:%d, " Angle=",iTestAngle:%d
237  if (angle<threshold) iTestProgress=2; // triggered
238  if (angle < (0.2 * threshold)) iTestProgress=0; // test is done
239  if (iTestDelay>100) iTestProgress=0; // abort test
240  break;
241  }
242  // End of code for white-box testing
243 #endif
244 }
enum quaternion quaternion_type
the quaternion type to be transmitted
Quaternion derived from full 9-axis sensor fusion.
Definition: sensor_fusion.h:70
#define ONEOVERSQRT2
1/sqrt(2)
float q0
scalar component
Definition: orientation.h:39
Quaternion derived from 3-axis mag only (auto compass algorithm)
Definition: sensor_fusion.h:66
float q3
z vector component
Definition: orientation.h:42
Quaternion derived from 3-axis gyro only (rotation)
Definition: sensor_fusion.h:67
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
Definition: sensor_fusion.h:68
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
Definition: sensor_fusion.h:69
struct ControlSubsystem * pControlSubsystem
quaternion structure definition
Definition: orientation.h:37
#define F180OVERPI
radians to degrees conversion = 180 / pi
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:65
float q2
y vector component
Definition: orientation.h:41
void qAeqAxB(Quaternion *pqA, const Quaternion *pqB)
function compute the quaternion product qA = qA * qB
Definition: orientation.c:969
float q1
x vector component
Definition: orientation.h:40
volatile uint8_t iPerturbation
test perturbation to be applied
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
Definition: control.h:66

+ Here is the call graph for this function: